package com.archgeek.rpc.proxy;

import com.archgeek.rpc.service.IUserInfoSerivce;
import com.archgeek.rpc.service.Request;
import com.archgeek.rpc.service.Response;
import com.archgeek.rpc.service.UserInfoSerivceImpl;
import sun.misc.ProxyGenerator;

import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;

/**
 *
 * https://cloud.tencent.com/developer/article/1336135
 *
 *
 * @author pizhihui
 * @date 2024-05-22 22:22
 */
public class ProxyDemo {


    public static void main(String[] args) throws IOException {


        normalInterafceInvoke();

        System.out.println("==================================分界线");

        ClassLoader classLoader = ProxyDemo.class.getClassLoader();

        UserInfoSerivceImpl obj = new UserInfoSerivceImpl();

        Class<?>[] interfaces = obj.getClass().getInterfaces();

        IUserInfoSerivce o = (IUserInfoSerivce) Proxy.newProxyInstance(
                classLoader,
                interfaces,
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        Class<?> declaringClass = method.getDeclaringClass();
                        Class<?>[] interfaces1 = declaringClass.getInterfaces();

                        System.out.println("调用方法前....");

                        Object res = method.invoke(obj, args);
                        System.out.println(res);

                        System.out.println("调用方法后....");

                        return res;
                    }
                });

        int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
        byte[] bytes = ProxyGenerator.generateProxyClass(
                "com.sun.proxy.$Proxy0", interfaces, accessFlags);

        // 这里我们将jdk生成的代理类输出了出来，方便后面分析使用
//        byte[] bytes = ProxyGenerator.generateProxyClass("$Proxy0",new Class[]{o.getClass()});
        FileOutputStream os = new FileOutputStream("Proxy1.class");
        os.write(bytes);
        os.close();
//
        o.queryUserInfoById(new Request().setName("invokation"));


        //新版本 jdk产生代理类
//        System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles", "true");
        // 老版本jdk
        //System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
//  该设置用于输出cglib动态代理产生的类
//        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "C:\\class");

    }

    private static void normalInterafceInvoke() {
        IUserInfoSerivce userInfoSerivce = new UserInfoSerivceImpl();
        Response response = userInfoSerivce.queryUserInfoById(new Request().setName("java"));
        System.out.println(response);
    }


}
